﻿using System;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace Felbot.IO {
    /// <summary>
    /// Allows control of the Felbot XML document.
    /// </summary>
    /// <typeparam name="T">This type must be a serializable class that can hold the contents of a Felbot Xml Document (.fbx) when passed it.</typeparam>
    public class XmlControl<T> where T : class, new() {
        /// <summary>The path to the .fbx file.</summary>
        private string m_Path;

        private T m_Document;

        /// <summary>Gets the document contents as type T.</summary>
        public T Document {
            get {
                return m_Document;
            }
            set {
                m_Document = value;
            }
        }

        /// <summary>Gets or sets the path to the document, also MOVES the document when set!</summary>
        public string Path {
            get {
                return m_Path;
            }
            set {
                try {
                    File.Move(m_Path, value);
                } catch (IOException e) {
                    if (MessageBox.Show("File.Move() Exception:\r\n" +
                                        e.ToString(),
                                        "Felbot",
                                        MessageBoxButtons.RetryCancel,
                                        MessageBoxIcon.Exclamation)
                            == DialogResult.Retry) {
                        Path = value;
                        return;
                    }
                }
                m_Path = value;
            }
        }

        /// <summary>Creates an Xml document. Also CREATES the .fbx file!</summary>
        /// <param name="a_sPath">The path to the file.</param>
        public XmlControl(string path) {
            m_Path = path;
            if (!Directory.Exists(new FileInfo(path).DirectoryName)) {
                try {
                    Directory.CreateDirectory(new FileInfo(path).DirectoryName);
                } catch (IOException e) {
                    MessageBox.Show("Directory.CreateDirectory() Exception:\r\n" +
                                    e.ToString(),
                                    "Felbot",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation);
                    m_Document = new T();
                    return;
                }
            }
            if (!File.Exists(path)) {
                try {
                    File.CreateText(path).Dispose();
                    m_Document = new T();
                } catch (IOException e) {
                    MessageBox.Show("File.CreateText() Exception:\r\n" +
                                    e.ToString(),
                                    "Felbot",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation);
                    return;
                }
            } else {
                try {
                    if (new FileInfo(path).Length == 0)
                        m_Document = new T();
                    else
                        using (StreamReader reader = new StreamReader(m_Path)) {
                            m_Document = (T) new XmlSerializer(typeof(T)).Deserialize(reader);
                            reader.Close();
                        }
                } catch (Exception e) {
                    MessageBox.Show("XmlSerializer.Deserialize() Exception:\r\n" +
                                    e.ToString(),
                                    "Felbot",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation);
                    m_Document = new T();
                    return;
                }
            }
        }

        /// <summary>Saves the Xml Document contents to the .fbx file.</summary>
        public void Save() {
            try {
                using (StreamWriter writer = new StreamWriter(m_Path)) {
                    new XmlSerializer(typeof(T)).Serialize(writer, m_Document);
                    writer.Close();
                }
            } catch (IOException e) {
                if (MessageBox.Show("XmlSerializer.Serialize() Exception:\r\n" +
                                    e.ToString(),
                                    "Felbot",
                                    MessageBoxButtons.RetryCancel,
                                    MessageBoxIcon.Exclamation)
                        == DialogResult.Retry) {
                    Save();
                }
            }
        }

        /// <summary>Deletes the .fbx file.</summary>
        public void Delete() {
            try {
                File.Delete(m_Path);
            } catch (IOException e) {
                if (MessageBox.Show("File.Delete() Exception:\r\n" +
                                    e.ToString(),
                                    "Felbot",
                                    MessageBoxButtons.RetryCancel,
                                    MessageBoxIcon.Exclamation)
                        == DialogResult.Retry) {
                    Delete();
                }
            }
        }
    }
}
